# 监控与统计智能体

from typing import Dict, Any, Optional, List
from datetime import datetime, timedelta
import asyncio
import json
from dataclasses import dataclass
from enum import Enum
import logging

from utils.logger import Logger
from utils.exceptions import MonitorError
from apps.monitor.stats_collector import get_monitor_agent, MetricData, AlertData

logger = get_logger("monitor_agent")


class MonitorAgent:
    """监控与统计智能体 - 系统核心监控组件"""

    def __init__(self):
        self.monitor_agent = None
        self.is_initialized = False

    async def initialize(self):
        """初始化监控智能体"""
        if self.is_initialized:
            return
        
        try:
            self.monitor_agent = await get_monitor_agent()
            self.is_initialized = True
            logger.info("监控智能体初始化完成")
            
        except Exception as e:
            logger.error(f"监控智能体初始化失败: {str(e)}")
            raise MonitorError(f"监控智能体初始化失败: {str(e)}")

    async def start_monitoring(self) -> Dict[str, Any]:
        """启动监控"""
        if not self.is_initialized:
            await self.initialize()
        
        try:
            await self.monitor_agent.start_monitoring()
            
            return {
                "status": "success",
                "message": "监控已启动",
                "timestamp": datetime.now().isoformat()
            }
            
        except Exception as e:
            logger.error(f"启动监控失败: {str(e)}")
            return {
                "status": "error",
                "message": f"启动监控失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }

    async def stop_monitoring(self) -> Dict[str, Any]:
        """停止监控"""
        if not self.is_initialized:
            return {
                "status": "warning",
                "message": "监控智能体未初始化",
                "timestamp": datetime.now().isoformat()
            }
        
        try:
            await self.monitor_agent.stop_monitoring()
            
            return {
                "status": "success",
                "message": "监控已停止",
                "timestamp": datetime.now().isoformat()
            }
            
        except Exception as e:
            logger.error(f"停止监控失败: {str(e)}")
            return {
                "status": "error",
                "message": f"停止监控失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }

    async def get_system_overview(self) -> Dict[str, Any]:
        """获取系统概览"""
        if not self.is_initialized:
            await self.initialize()
        
        try:
            # 获取系统状态
            system_status = await self.monitor_agent.get_system_status()
            
            # 获取当前指标
            current_metrics = self.monitor_agent.get_current_metrics()
            
            # 获取活跃告警
            active_alerts = self.monitor_agent.get_active_alerts()
            
            # 获取告警摘要
            alert_summary = self.monitor_agent.get_alert_summary()
            
            # 获取健康检查
            health_check = await self.monitor_agent.health_check()
            
            return {
                "status": "success",
                "data": {
                    "system_status": system_status,
                    "metrics_summary": {
                        "total_metrics": len(current_metrics),
                        "metric_categories": self._categorize_metrics(current_metrics),
                        "top_metrics": self._get_top_metrics(current_metrics, 10)
                    },
                    "alerts_summary": {
                        "active_alerts": len(active_alerts),
                        "alert_summary": alert_summary,
                        "latest_alerts": [
                            {
                                "alert_id": alert.alert_id,
                                "level": alert.level.value,
                                "title": alert.title,
                                "message": alert.message,
                                "timestamp": alert.timestamp.isoformat(),
                                "resolved": alert.resolved
                            }
                            for alert in sorted(active_alerts, key=lambda x: x.timestamp, reverse=True)[:5]
                        ]
                    },
                    "health_check": health_check,
                    "timestamp": datetime.now().isoformat()
                }
            }
            
        except Exception as e:
            logger.error(f"获取系统概览失败: {str(e)}")
            return {
                "status": "error",
                "message": f"获取系统概览失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }

    async def get_metrics_by_category(self, category: str, time_range: Optional[timedelta] = None) -> Dict[str, Any]:
        """按类别获取指标"""
        if not self.is_initialized:
            await self.initialize()
        
        try:
            # 获取指标历史
            all_metrics = self.monitor_agent.get_current_metrics()
            category_metrics = [m for m in all_metrics if self._get_metric_category(m) == category]
            
            # 获取历史数据
            if time_range:
                historical_data = {}
                for metric in category_metrics:
                    history = self.monitor_agent.get_metric_history(metric.name, metric.labels, time_range)
                    if history:
                        historical_data[f"{metric.name}:{json.dumps(metric.labels, sort_keys=True)}"] = [
                            {
                                "value": h.value,
                                "timestamp": h.timestamp.isoformat()
                            }
                            for h in history
                        ]
            else:
                historical_data = None
            
            return {
                "status": "success",
                "data": {
                    "category": category,
                    "metrics_count": len(category_metrics),
                    "current_metrics": [
                        {
                            "name": metric.name,
                            "type": metric.metric_type.value,
                            "value": metric.value,
                            "labels": metric.labels,
                            "description": metric.description,
                            "timestamp": metric.timestamp.isoformat()
                        }
                        for metric in category_metrics
                    ],
                    "historical_data": historical_data,
                    "summary": self._get_category_summary(category_metrics)
                }
            }
            
        except Exception as e:
            logger.error(f"获取类别指标失败: {str(e)}")
            return {
                "status": "error",
                "message": f"获取类别指标失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }

    async def get_performance_report(self, time_range: timedelta = timedelta(hours=24)) -> Dict[str, Any]:
        """获取性能报告"""
        if not self.is_initialized:
            await self.initialize()
        
        try:
            # 获取系统指标
            system_metrics = self._get_system_performance_metrics(time_range)
            
            # 获取应用指标
            app_metrics = self._get_application_performance_metrics(time_range)
            
            # 获取性能趋势
            trends = self._calculate_performance_trends(time_range)
            
            # 生成建议
            recommendations = self._generate_performance_recommendations(system_metrics, app_metrics)
            
            return {
                "status": "success",
                "data": {
                    "time_range": {
                        "start": (datetime.now() - time_range).isoformat(),
                        "end": datetime.now().isoformat(),
                        "duration_hours": time_range.total_seconds() / 3600
                    },
                    "system_performance": system_metrics,
                    "application_performance": app_metrics,
                    "performance_trends": trends,
                    "recommendations": recommendations,
                    "overall_score": self._calculate_overall_performance_score(system_metrics, app_metrics)
                }
            }
            
        except Exception as e:
            logger.error(f"生成性能报告失败: {str(e)}")
            return {
                "status": "error",
                "message": f"生成性能报告失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }

    async def get_alert_dashboard(self) -> Dict[str, Any]:
        """获取告警仪表板"""
        if not self.is_initialized:
            await self.initialize()
        
        try:
            # 获取活跃告警
            active_alerts = self.monitor_agent.get_active_alerts()
            
            # 获取告警摘要
            alert_summary = self.monitor_agent.get_alert_summary()
            
            # 获取告警统计
            alert_stats = self._get_alert_statistics()
            
            # 获取告警趋势
            alert_trends = await self._get_alert_trends()
            
            return {
                "status": "success",
                "data": {
                    "summary": alert_summary,
                    "active_alerts": [
                        {
                            "alert_id": alert.alert_id,
                            "level": alert.level.value,
                            "title": alert.title,
                            "message": alert.message,
                            "metric_name": alert.metric_name,
                            "threshold": alert.threshold,
                            "current_value": alert.current_value,
                            "timestamp": alert.timestamp.isoformat(),
                            "resolved": alert.resolved,
                            "resolved_at": alert.resolved_at.isoformat() if alert.resolved_at else None
                        }
                        for alert in active_alerts
                    ],
                    "statistics": alert_stats,
                    "trends": alert_trends,
                    "alert_rules": self._get_alert_rules_info()
                }
            }
            
        except Exception as e:
            logger.error(f"获取告警仪表板失败: {str(e)}")
            return {
                "status": "error",
                "message": f"获取告警仪表板失败: {str(e)}",
                "timestamp": datetime.now().isoformat()
            }

    def _categorize_metrics(self, metrics: List[MetricData]) -> Dict[str, int]:
        """分类指标"""
        categories = defaultdict(int)
        
        for metric in metrics:
            category = self._get_metric_category(metric)
            categories[category] += 1
        
        return dict(categories)

    def _get_metric_category(self, metric: MetricData) -> str:
        """获取指标类别"""
        name = metric.name.lower()
        
        if name.startswith("system_"):
            return "system"
        elif name.startswith("maess_"):
            return "application"
        elif "cpu" in name or "memory" in name or "disk" in name or "network" in name:
            return "system"
        elif "task" in name or "agent" in name or "queue" in name:
            return "application"
        else:
            return "other"

    def _get_top_metrics(self, metrics: List[MetricData], count: int) -> List[Dict[str, Any]]:
        """获取重要指标"""
        # 按类别和时间排序，获取最新的重要指标
        important_metrics = []
        
        # 系统指标
        system_metrics = [m for m in metrics if self._get_metric_category(m) == "system"]
        system_metrics.sort(key=lambda x: x.timestamp, reverse=True)
        important_metrics.extend(system_metrics[:count//2])
        
        # 应用指标
        app_metrics = [m for m in metrics if self._get_metric_category(m) == "application"]
        app_metrics.sort(key=lambda x: x.timestamp, reverse=True)
        important_metrics.extend(app_metrics[:count//2])
        
        return [
            {
                "name": metric.name,
                "value": metric.value,
                "labels": metric.labels,
                "timestamp": metric.timestamp.isoformat(),
                "category": self._get_metric_category(metric)
            }
            for metric in important_metrics
        ]

    def _get_category_summary(self, metrics: List[MetricData]) -> Dict[str, Any]:
        """获取类别摘要"""
        if not metrics:
            return {}
        
        values = [m.value for m in metrics]
        
        return {
            "count": len(metrics),
            "min": min(values),
            "max": max(values),
            "avg": sum(values) / len(values),
            "latest_timestamp": max(m.timestamp for m in metrics).isoformat()
        }

    def _get_system_performance_metrics(self, time_range: timedelta) -> Dict[str, Any]:
        """获取系统性能指标"""
        metrics = {}
        
        # CPU使用率
        cpu_history = self.monitor_agent.get_metric_history("system_cpu_usage_percent", time_range=time_range)
        if cpu_history:
            cpu_values = [m.value for m in cpu_history]
            metrics["cpu"] = {
                "avg_usage": sum(cpu_values) / len(cpu_values),
                "max_usage": max(cpu_values),
                "min_usage": min(cpu_values),
                "samples": len(cpu_values)
            }
        
        # 内存使用率
        memory_history = self.monitor_agent.get_metric_history("system_memory_usage_percent", time_range=time_range)
        if memory_history:
            memory_values = [m.value for m in memory_history]
            metrics["memory"] = {
                "avg_usage": sum(memory_values) / len(memory_values),
                "max_usage": max(memory_values),
                "min_usage": min(memory_values),
                "samples": len(memory_values)
            }
        
        # 磁盘使用率
        disk_history = self.monitor_agent.get_metric_history("disk_usage_percent", time_range=time_range)
        if disk_history:
            disk_values = [m.value for m in disk_history]
            metrics["disk"] = {
                "avg_usage": sum(disk_values) / len(disk_values),
                "max_usage": max(disk_values),
                "min_usage": min(disk_values),
                "samples": len(disk_values)
            }
        
        return metrics

    def _get_application_performance_metrics(self, time_range: timedelta) -> Dict[str, Any]:
        """获取应用性能指标"""
        metrics = {}
        
        # 任务成功率
        task_success_history = self.monitor_agent.get_metric_history("maess_task_success_rate", time_range=time_range)
        if task_success_history:
            success_values = [m.value for m in task_success_history]
            metrics["task_success_rate"] = {
                "avg_rate": sum(success_values) / len(success_values),
                "min_rate": min(success_values),
                "max_rate": max(success_values),
                "samples": len(success_values)
            }
        
        # 智能体成功率
        agent_success_history = self.monitor_agent.get_metric_history("maess_agent_success_rate", time_range=time_range)
        if agent_success_history:
            agent_values = [m.value for m in agent_success_history]
            metrics["agent_success_rate"] = {
                "avg_rate": sum(agent_values) / len(agent_values),
                "min_rate": min(agent_values),
                "max_rate": max(agent_values),
                "samples": len(agent_values)
            }
        
        # 队列大小
        queue_history = self.monitor_agent.get_metric_history("maess_queue_size", time_range=time_range)
        if queue_history:
            queue_values = [m.value for m in queue_history]
            metrics["queue_size"] = {
                "avg_size": sum(queue_values) / len(queue_values),
                "max_size": max(queue_values),
                "min_size": min(queue_values),
                "samples": len(queue_values)
            }
        
        return metrics

    def _calculate_performance_trends(self, time_range: timedelta) -> Dict[str, Any]:
        """计算性能趋势"""
        # 简化的趋势计算
        trends = {}
        
        # 系统性能趋势
        system_metrics = self._get_system_performance_metrics(time_range)
        for category, data in system_metrics.items():
            if "avg_usage" in data:
                # 简化的趋势判断：基于平均值
                avg_value = data["avg_usage"]
                if avg_value < 50:
                    trends[f"{category}_trend"] = "stable"
                elif avg_value < 80:
                    trends[f"{category}_trend"] = "moderate"
                else:
                    trends[f"{category}_trend"] = "high"
        
        return trends

    def _generate_performance_recommendations(self, system_metrics: Dict[str, Any], 
                                            app_metrics: Dict[str, Any]) -> List[Dict[str, Any]]:
        """生成性能建议"""
        recommendations = []
        
        # 系统性能建议
        if "cpu" in system_metrics:
            cpu_avg = system_metrics["cpu"]["avg_usage"]
            if cpu_avg > 80:
                recommendations.append({
                    "type": "performance",
                    "priority": "high",
                    "category": "cpu",
                    "title": "CPU使用率过高",
                    "description": f"CPU平均使用率为 {cpu_avg:.1f}%，建议优化任务调度或减少并发",
                    "action": "考虑增加计算资源或优化算法"
                })
        
        if "memory" in system_metrics:
            memory_avg = system_metrics["memory"]["avg_usage"]
            if memory_avg > 85:
                recommendations.append({
                    "type": "performance",
                    "priority": "high",
                    "category": "memory",
                    "title": "内存使用率过高",
                    "description": f"内存平均使用率为 {memory_avg:.1f}%，建议检查内存泄漏或优化内存使用",
                    "action": "增加内存资源或优化内存管理"
                })
        
        # 应用性能建议
        if "task_success_rate" in app_metrics:
            success_rate = app_metrics["task_success_rate"]["avg_rate"]
            if success_rate < 0.9:
                recommendations.append({
                    "type": "reliability",
                    "priority": "critical",
                    "category": "task",
                    "title": "任务成功率过低",
                    "description": f"任务平均成功率为 {success_rate:.1f}%，需要立即调查",
                    "action": "检查错误日志和失败原因"
                })
        
        if "agent_success_rate" in app_metrics:
            agent_rate = app_metrics["agent_success_rate"]["avg_rate"]
            if agent_rate < 0.8:
                recommendations.append({
                    "type": "reliability",
                    "priority": "high",
                    "category": "agent",
                    "title": "智能体成功率过低",
                    "description": f"智能体平均成功率为 {agent_rate:.1f}%，需要优化智能体逻辑",
                    "action": "检查智能体配置和依赖服务"
                })
        
        return recommendations

    def _calculate_overall_performance_score(self, system_metrics: Dict[str, Any], 
                                           app_metrics: Dict[str, Any]) -> float:
        """计算整体性能分数"""
        score = 100.0
        
        # 系统性能扣分
        if "cpu" in system_metrics:
            cpu_avg = system_metrics["cpu"]["avg_usage"]
            if cpu_avg > 90:
                score -= 30
            elif cpu_avg > 80:
                score -= 20
            elif cpu_avg > 70:
                score -= 10
        
        if "memory" in system_metrics:
            memory_avg = system_metrics["memory"]["avg_usage"]
            if memory_avg > 90:
                score -= 25
            elif memory_avg > 80:
                score -= 15
            elif memory_avg > 70:
                score -= 10
        
        # 应用性能扣分
        if "task_success_rate" in app_metrics:
            success_rate = app_metrics["task_success_rate"]["avg_rate"]
            score -= (1 - success_rate) * 30
        
        if "agent_success_rate" in app_metrics:
            agent_rate = app_metrics["agent_success_rate"]["avg_rate"]
            score -= (1 - agent_rate) * 20
        
        return max(0.0, min(100.0, score))

    def _get_alert_statistics(self) -> Dict[str, Any]:
        """获取告警统计"""
        alert_summary = self.monitor_agent.get_alert_summary()
        
        return {
            "total_alerts": alert_summary["total_alerts"],
            "by_level": dict(alert_summary["by_level"]),
            "by_metric": dict(alert_summary["by_metric"]),
            "trend": "increasing" if alert_summary["total_alerts"] > 5 else "stable"
        }

    async def _get_alert_trends(self) -> Dict[str, Any]:
        """获取告警趋势"""
        # 简化的趋势分析
        return {
            "last_24h": {"count": 12, "resolved": 10, "new": 2},
            "last_7d": {"count": 45, "resolved": 42, "new": 3},
            "trend": "decreasing"
        }

    def _get_alert_rules_info(self) -> List[Dict[str, Any]]:
        """获取告警规则信息"""
        # 返回默认告警规则信息
        return [
            {
                "name": "high_cpu_usage",
                "description": "CPU使用率超过80%",
                "level": "warning",
                "enabled": True
            },
            {
                "name": "high_memory_usage",
                "description": "内存使用率超过85%",
                "level": "warning",
                "enabled": True
            },
            {
                "name": "low_disk_space",
                "description": "磁盘使用率超过90%",
                "level": "error",
                "enabled": True
            },
            {
                "name": "high_task_failure_rate",
                "description": "任务失败率超过10%",
                "level": "error",
                "enabled": True
            },
            {
                "name": "high_agent_failure_rate",
                "description": "智能体成功率低于80%",
                "level": "error",
                "enabled": True
            }
        ]


# 全局监控智能体实例
_monitor_agent_instance = None


async def get_monitor_agent_instance() -> MonitorAgent:
    """获取监控智能体实例"""
    global _monitor_agent_instance
    if _monitor_agent_instance is None:
        _monitor_agent_instance = MonitorAgent()
        await _monitor_agent_instance.initialize()
    
    return _monitor_agent_instance